﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Dynamic;
using Umbraco.Forms.Core;
using Umbraco.Forms.Data.Storage;
using Umbraco.Forms.Core.Enums;

namespace ContourStrikesAgain.Razor
{
    public class DynamicRecord : DynamicObject
    {

        //take care of dictionary item fields

        private Record _record;
        internal DynamicRecordList ownerList;


        public DynamicRecord(Record record)
        {
            _record = record;

        }

        public DynamicRecord()
        {

        }

        public bool HasField(string caption)
        {
            return _record.RecordFields.Where(f => f.Value.Field.Caption == caption) != null;
        }

        public bool HasField(Guid fieldId)
        {

            return _record.RecordFields.Where(f => f.Value.Field.Id == fieldId) != null;
        }

        public RecordField GetField(string caption)
        {
            return _record.RecordFields.Where(f => f.Value.Field.Caption == caption).First().Value;
        }

        public RecordField GetField(Guid fieldId)
        {
            return _record.RecordFields.Where(f => f.Value.Field.Id == fieldId).First().Value;

        }
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            string name = binder.Name;

            if (_record != null)
            {

                if (_record.RecordFields.Where(f => f.Value.Field.Caption == name) != null)
                {
                    result = _record.RecordFields.Where(f => f.Value.Field.Caption == name).First().Value.ValuesAsString();
                    return true;
                }


                // failback to default properties
                try
                {
                    result = _record.GetType().InvokeMember(binder.Name,
                                                      System.Reflection.BindingFlags.GetProperty |
                                                      System.Reflection.BindingFlags.Instance |
                                                      System.Reflection.BindingFlags.Public |
                                                      System.Reflection.BindingFlags.NonPublic,
                                                      null,
                                                      _record,
                                                      null);
                    return true;
                }
                catch
                {
                }

                //return false because we have a record item now but the property doesn't exist
                result = null;
                return false;
            }

            result = null;
            //return true because the _record is likely null, meaning we're in test mode
            return true;
        }

        public DateTime Created
        {
            get { if (_record == null) return DateTime.MinValue; return _record.Created; }
        }

        public string Form
        {
            get { if (_record == null) return null; return _record.Form.ToString(); }

        }
        public string Id
        {
            get { if (_record == null) return null; return _record.Id.ToString(); }
        }

        public string IP
        {
            get { if (_record == null) return null; return _record.IP; }
        }

        public object MemberKey
        {
            get { if (_record == null) return null; return _record.MemberKey; }
        }

        public Dictionary<Guid, RecordField> RecordFields
        {
            get { if (_record == null) return null; return _record.RecordFields; }
        }
        public FormState? State
        {
            get { if (_record == null) return null; return _record.State; }
        }

        public int UmbracoPageId
        {
            get { if (_record == null) return 0; return _record.UmbracoPageId; }
        }

        public DateTime Updated
        {
            get { if (_record == null) return DateTime.MinValue; return _record.Updated; }
        }

    }
}